package com.iplant.mes.serviceImpl;

import com.iplant.ams.service.po.ams.fxt.DMSFrockLedger;
import com.iplant.ams.service.po.dms.DMSDeviceLedger;
import com.iplant.ams.service.po.dms.scada.alarm.DMSDeviceAlarm;
import com.iplant.ams.service.po.dms.scada.status.DMSDeviceStatus;
import com.iplant.ams.serviceImpl.DMSServiceImpl;
import com.iplant.ams.serviceImpl.dao.dms.DMSDeviceLedgerDAO;
import com.iplant.aps.service.apsenum.aps.APSShiftPeriod;
import com.iplant.aps.service.apsenum.oms.OMSOrderStatus;
import com.iplant.aps.service.po.aps.APSTaskPart;
import com.iplant.aps.service.po.aps.APSTaskPartPoint;
import com.iplant.aps.service.po.aps.APSTaskPartPointDay;
import com.iplant.aps.service.po.oms.OMSOrder;
import com.iplant.base.po.OutResult;
import com.iplant.base.po.Pagination;
import com.iplant.base.po.ServiceResult;
import com.iplant.base.po.enums.ExceptionTypes;
import com.iplant.base.utils.general.CalendarTool;
import com.iplant.base.utils.general.StringUtils;
import com.iplant.base.utils.sql.orm.ORMUtils;
import com.iplant.base.utils.sql.orm.PoService;
import com.iplant.basic.service.po.bms.BMSClassInfo;
import com.iplant.basic.service.po.bms.BMSClassRange;
import com.iplant.basic.service.po.bms.BMSEmployee;
import com.iplant.basic.service.po.fmc.FMCCodeScanningGunConfig;
import com.iplant.basic.service.po.fmc.FMCIPConfig;
import com.iplant.basic.service.po.fmc.FMCShift;
import com.iplant.basic.service.po.fmc.FMCStation;
import com.iplant.basic.serviceImpl.FMCServiceImpl;
import com.iplant.mes.service.AndonService;
import com.iplant.mes.service.mesenum.andon.AndonFinishSituationType;
import com.iplant.mes.service.mesenum.andon.AndonStationStatusTypes;
import com.iplant.mes.service.mesenum.sfc.SFCTaskStatus;
import com.iplant.mes.service.po.andon.AndonProductData;
import com.iplant.mes.service.po.andon.AndonStationStatus;
import com.iplant.mes.service.po.andon.AndonStationStatusWorkerInfo;
import com.iplant.mes.service.po.andon.productData.*;
import com.iplant.mes.service.po.exc.EXCProductRepair;
import com.iplant.mes.service.po.exc.EXCProductRepairItem;
import com.iplant.mes.service.po.exc.EXCUnusualTask;
import com.iplant.mes.service.po.ipt.IPTValue;
import com.iplant.mes.service.po.sfc.*;
import com.iplant.mes.serviceImpl.dao.sfc.SFCWorkpieceRecordDAO;
import com.iplant.pdm.service.basicenum.pdm.PDMComponentTypes;
import com.iplant.pdm.service.po.bop.FPCRoutePartPoint;
import com.iplant.pdm.service.po.bop.partpoint.FPCRouteStep;
import com.iplant.pdm.service.po.fpc.FPCProduct;
import com.iplant.pdm.service.po.fpc.FPCProductCom;
import com.iplant.pdm.service.po.mss.MSSBOMItem;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class AndonServiceImpl implements AndonService {

    //region 构造函数
    public AndonServiceImpl() {
    }
    //endregion

    //region 单实例

    private static AndonService Instance = null;

    public static AndonService getInstance() {
        if (Instance == null)
            Instance = new AndonServiceImpl();

        return Instance;
    }

    //endregion

    //region POService
    PoService<SFCTaskSelf> mSFCTaskSelfService = ORMUtils.GetPoService(SFCTaskSelf.class);
    PoService<APSTaskPartPointDay> mAPSTaskPartPointDayService = ORMUtils.GetPoService(APSTaskPartPointDay.class);
    PoService<SFCLoginEvent> mSFCLoginEventService = ORMUtils.GetPoService(SFCLoginEvent.class);
    PoService<SFCTaskIPT> mSFCTaskIPTService = ORMUtils.GetPoService(SFCTaskIPT.class);
    PoService<BMSClassRange> mBMSClassRangeService = ORMUtils.GetPoService(BMSClassRange.class);
    PoService<FPCRouteStep> mFPCRouteStepService = ORMUtils.GetPoService(FPCRouteStep.class);
    PoService<IPTValue> mIPTValueService = ORMUtils.GetPoService(IPTValue.class);
    PoService<FPCRoutePartPoint> mFPCRoutePartPointService = ORMUtils.GetPoService(FPCRoutePartPoint.class);
    PoService<SFCWorkpieceRecord> mSFCWorkpieceRecordService = ORMUtils.GetPoService(SFCWorkpieceRecord.class);
    PoService<SFCTaskReport> mSFCTaskReportService = ORMUtils.GetPoService(SFCTaskReport.class);
    PoService<APSTaskPartPoint> mAPSTaskPartPointService = ORMUtils.GetPoService(APSTaskPartPoint.class);
    PoService<APSTaskPart> mAPSTaskPartService = ORMUtils.GetPoService(APSTaskPart.class);
    PoService<SFCFrockBindRecord> mSFCFrockBindRecordService = ORMUtils.GetPoService(SFCFrockBindRecord.class);
    PoService<MSSBOMItem> mMSSBOMItemService = ORMUtils.GetPoService(MSSBOMItem.class);
    PoService<SFCStationMaterial> mSFCStationMaterialService = ORMUtils.GetPoService(SFCStationMaterial.class);
    PoService<SFCBoxReport> mSFCBoxReportService = ORMUtils.GetPoService(SFCBoxReport.class);
    PoService<OMSOrder> mOMSOrderService = ORMUtils.GetPoService(OMSOrder.class);
    PoService<DMSFrockLedger> mDMSFrockLedgerService = ORMUtils.GetPoService(DMSFrockLedger.class);
    PoService<SFCWorkpieceResume> mSFCWorkpieceResumeService = ORMUtils.GetPoService(SFCWorkpieceResume.class);
    PoService<SFCMaterialLoadingRecord> mSFCMaterialLoadingRecordService =
            ORMUtils.GetPoService(SFCMaterialLoadingRecord.class);
    PoService<SFCTaskStartCheck> mSFCTaskStartCheckService = ORMUtils.GetPoService(SFCTaskStartCheck.class);
    PoService<BMSClassInfo> mBMSClassInfoService = ORMUtils.GetPoService(BMSClassInfo.class);

    PoService<FMCStation> mFMCStationService = ORMUtils.GetPoService(FMCStation.class);
    PoService<FMCIPConfig> mFMCIPConfigService = ORMUtils.GetPoService(FMCIPConfig.class);
    PoService<FMCCodeScanningGunConfig> mFMCCodeScanningGunConfigService =
            ORMUtils.GetPoService(FMCCodeScanningGunConfig.class);
    PoService<SFCAssemblyRecord> mSFCAssemblyRecordService =
            ORMUtils.GetPoService(SFCAssemblyRecord.class);
    PoService<EXCProductRepairItem> mEXCProductRepairItemService =
            ORMUtils.GetPoService(EXCProductRepairItem.class);
    PoService<EXCProductRepair> mEXCProductRepairService = ORMUtils.GetPoService(EXCProductRepair.class);
    PoService<FPCProductCom> mFPCProductComService = ORMUtils.GetPoService(FPCProductCom.class);
    PoService<SFCTaskParamItem> mSFCTaskParamItemService = ORMUtils.GetPoService(SFCTaskParamItem.class);
    PoService<FPCProduct> mFPCProductService = ORMUtils.GetPoService(FPCProduct.class);
    PoService<EXCUnusualTask> mEXCUnusualTaskService = ORMUtils.GetPoService(EXCUnusualTask.class);
    PoService<DMSDeviceLedger> mDMSDeviceLedgerService = ORMUtils.GetPoService(DMSDeviceLedger.class);
    //endregion

    //region 工位状态监控
    @Override
    public ServiceResult<List<AndonStationStatus>> Andon_QueryStationStatusList(BMSEmployee wLoginUser, int wOrderID) {
        ServiceResult<List<AndonStationStatus>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            //①获取激活的工位列表
            List<FMCStation> wFMCStationList = FMCServiceImpl.getInstance().FMC_QueryStationList(wLoginUser, -1,
                    -1, null, -1, -1, "", 1, -1, Pagination.getNewMaxSize()).Result;
            if (wFMCStationList == null || wFMCStationList.size() == 0) {
                return wResult;
            }
            wFMCStationList.sort(Comparator.comparing(FMCStation::getCode));
            //②获取今日派工任务列表
            Calendar wSTime = Calendar.getInstance();
            wSTime.set(wSTime.get(Calendar.YEAR), wSTime.get(Calendar.MONTH), wSTime.get(Calendar.DATE), 0, 0, 0);
            wSTime.set(Calendar.MILLISECOND, 0);

            Calendar wETime = Calendar.getInstance();
            wETime.set(wSTime.get(Calendar.YEAR), wSTime.get(Calendar.MONTH), wSTime.get(Calendar.DATE), 23, 59, 59);

            Map<String, Object> wParams = new HashMap<String, Object>();
            wParams.put("StaStartTime", wSTime);
            wParams.put("StaEndTime", wETime);
            wParams.put("Active", 1);
            wParams.put("Status", StringUtils.Join(",", new ArrayList<>(Arrays.asList(SFCTaskStatus.Todo.getValue(),
                    SFCTaskStatus.Doing.getValue(), SFCTaskStatus.Suspend.getValue(), SFCTaskStatus.Done.getValue(),
                    SFCTaskStatus.Reported.getValue()))));

            if (wOrderID > 0) {
                wParams.put("OrderID", wOrderID);
            }
            List<SFCTaskSelf> wSFCTaskSelfList = mSFCTaskSelfService.SelectPOList(wLoginUser, wParams,
                    Pagination.getNewMaxSize(),
                    wErrorCode);
            Map<Integer, List<SFCTaskSelf>> wStationIDTaskSelfListMap = wSFCTaskSelfList.stream()
                    .collect(Collectors.groupingBy(SFCTaskSelf::getStationID));
            //③获取任务的订单列表
            List<OMSOrder> wOrderList = new ArrayList<>();
            if (wSFCTaskSelfList != null && wSFCTaskSelfList.size() > 0) {
                List<Integer> wOrderIDList =
                        wSFCTaskSelfList.stream().map(p -> p.OrderID).distinct().collect(Collectors.toList());
                wParams.clear();
                wOrderList = mOMSOrderService.SelectPOList(wLoginUser, wOrderIDList, wParams,
                        Pagination.getNewMaxSize(),
                        wErrorCode);
            }
            //③获取当前班次
            List<FMCShift> wFMCShiftList =
                    FMCServiceImpl.getInstance().FMC_QueryShiftList(wLoginUser, 9, 0, 0, 0,
                            Pagination.getNewMaxSize()).Result;
            if (wFMCShiftList == null || wFMCShiftList.size() <= 0) {
                wResult.FaultCode += "未查询到工厂班次设置，请联系系统管理员!";
                return wResult;
            }

            int wYear = Calendar.getInstance().get(Calendar.YEAR);
            int wMonth = Calendar.getInstance().get(Calendar.MONTH);
            int wDate = Calendar.getInstance().get(Calendar.DATE);

            FMCShift wCurrentShift = new FMCShift();
            for (FMCShift wFMCShift : wFMCShiftList) {
                wFMCShift.StartTime.set(wYear, wMonth, wDate);
                wFMCShift.EndTime.set(wYear, wMonth, wDate);
                if (Calendar.getInstance().compareTo(wFMCShift.StartTime) >= 0 && Calendar.getInstance().compareTo(wFMCShift.EndTime) <= 0) {
                    wCurrentShift = wFMCShift;
                }
            }
            if (wCurrentShift.ID <= 0) {
                wResult.FaultCode += "未查询到当前班次信息，请检查班次设置!";
                return wResult;
            }
            //④获取未完成的异常信息
            wParams.clear();
            wParams.put("Status", 0);
            List<EXCUnusualTask> wEXCUnusualTaskList =
                    EXCServiceImpl.getInstance().BPM_QueryEmployeeAllWeb(wLoginUser, wParams,
                            Pagination.getNewMaxSize()).Result;
            Map<Integer, List<EXCUnusualTask>> wStationIDExcListMap = wEXCUnusualTaskList.stream()
                    .collect(Collectors.groupingBy(EXCUnusualTask::getStationID));
            //④获取设备状态列表
            List<DMSDeviceStatus> wDMSDeviceStatusList =
                    DMSServiceImpl.getInstance().DMS_CurrentDeviceStatusList(wLoginUser,
                            -1, "", "", "", -1, -1, -1, -1, -1, -1, Pagination.getNewMaxSize()).Result;
            Map<Integer, DMSDeviceStatus> wDeviceIDStatusMap =
                    wDMSDeviceStatusList.stream().collect(Collectors.toMap(DMSDeviceStatus::getDeviceID
                            , p -> p));

            //①获取设备台账
            wParams.clear();
            wParams.put("Active", 1);
            List<DMSDeviceLedger> wDMSDeviceLedgerList = mDMSDeviceLedgerService.SelectPOList(wLoginUser, wParams,
                    Pagination.getNewMaxSize(),
                    wErrorCode);
            Map<Integer, DMSDeviceLedger> wIDDeviceLedgerMap =
                    wDMSDeviceLedgerList.stream().collect(Collectors.toMap(DMSDeviceLedger::getID
                            , p -> p));

            //若给了订单，则查询订单的工单列表
            List<SFCTaskSelf> wOrderSelfList = new ArrayList<>();
            if (wOrderID > 0) {
                wParams.clear();
                wParams.put("OrderID", wOrderID);
                wOrderSelfList = mSFCTaskSelfService.SelectPOList(wLoginUser, wParams,
                        Pagination.getNewMaxSize(),
                        wErrorCode);
            }

            //⑤遍历工位列表，组装数据
            AndonStationStatus wAndonStationStatus;
            for (FMCStation wFMCStation : wFMCStationList) {
                int stationStatus = Andon_GetStationStatus(wLoginUser, wFMCStation, wStationIDTaskSelfListMap,
                        wStationIDExcListMap,
                        wErrorCode);
                int wDeviceID = 0;
                String wDeviceName = "";
                if (wFMCStation.DeviceID != null && wFMCStation.DeviceID.size() > 0) {
                    wDeviceID = wFMCStation.DeviceID.get(0);
                    wDeviceName = wFMCStation.DeviceName.split(",")[0];
                }

                List<OMSOrder> wStatoinOrderList = new ArrayList<>();
                if (wStationIDTaskSelfListMap.containsKey(wFMCStation.ID)) {
                    List<SFCTaskSelf> wTempList = wStationIDTaskSelfListMap.get(wFMCStation.ID);
                    wStatoinOrderList =
                            wOrderList.stream().filter(p -> wTempList.stream().anyMatch(q -> q.OrderID == p.ID)).collect(Collectors.toList());
                }

                int deviceStatus = 0;
                if (wDeviceID > 0 && wDeviceIDStatusMap.containsKey(wDeviceID)) {
                    DMSDeviceStatus wDMSDeviceStatus = wDeviceIDStatusMap.get(wDeviceID);
                    deviceStatus = wDMSDeviceStatus.Status;
                }

                //获取作业人员信息
                List<AndonStationStatusWorkerInfo> wWorkerInfoList = Andon_GetWorkerInfoList(wLoginUser, wFMCStation,
                        wStationIDTaskSelfListMap,
                        wErrorCode);
                //获取今日完成数
                float todayFinishedFQTY = Andon_GetTodayFinishedFQTY(wFMCStation, wStationIDTaskSelfListMap);
                //获取当班完成数
                float shiftFinishedFQTY = Andon_GetShiftFinishedFQTY(wFMCStation, wStationIDTaskSelfListMap,
                        wCurrentShift);

                String wDeviceStatusText = DMSDeviceLedgerDAO.getInstance().DMS_DeviceStatusText(wLoginUser,
                        deviceStatus, wErrorCode);

                //统计总数
                float wTotal = 0.0f;
                List<SFCTaskSelf> wStationSelfList =
                        wOrderSelfList.stream().filter(p -> p.StationID == wFMCStation.ID).collect(Collectors.toList());
                if (wStationSelfList.size() > 0) {
                    wTotal = (float) wStationSelfList.stream().mapToDouble(p -> p.ActNum).sum();
                }

                wAndonStationStatus = new AndonStationStatus(wFMCStation.ID, wFMCStation.Name, stationStatus,
                        AndonStationStatusTypes.getEnumType(stationStatus).getLabel()
                        , wStatoinOrderList, wDeviceID, wDeviceName, deviceStatus,
                        wDeviceStatusText, wWorkerInfoList,
                        todayFinishedFQTY, shiftFinishedFQTY);
                wAndonStationStatus.TotalFQTY = wTotal;
                if (wDeviceID > 0 && wIDDeviceLedgerMap.containsKey(wDeviceID)) {
                    wAndonStationStatus.ModelID = wIDDeviceLedgerMap.get(wDeviceID).ModelID;
                }

                if (wTotal > 0 && wAndonStationStatus.OrderList.size() <= 0) {
                    wParams.clear();
                    wParams.put("ID", wOrderID);
                    OMSOrder omsOrder = mOMSOrderService.SelectPO(wLoginUser, wParams,
                            wErrorCode);
                    if (omsOrder != null && omsOrder.ID > 0) {
                        wAndonStationStatus.OrderList.add(omsOrder);
                    }
                }

                wResult.Result.add(wAndonStationStatus);
            }

            wResult.setFaultCode(ExceptionTypes.getEnumType(wErrorCode.Result).getLabel());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            log.error(e.toString());
        }
        return wResult;
    }

    /**
     * 获取当班完成数
     */
    private float Andon_GetShiftFinishedFQTY(FMCStation wFMCStation,
                                             Map<Integer, List<SFCTaskSelf>> wStationIDTaskSelfListMap,
                                             FMCShift wCurrentShift) {
        float wResult = 0.0f;
        try {
            if (!wStationIDTaskSelfListMap.containsKey(wFMCStation.ID)) {
                return wResult;
            }

            wResult =
                    (float) wStationIDTaskSelfListMap.get(wFMCStation.ID).stream().filter(p -> p.ShiftType
                            == wCurrentShift.ShiftType).mapToDouble(p -> p.ActNum).sum();
        } catch (Exception ex) {
            log.error("Andon_GetShiftFinishedFQTY", ex);
        }
        return wResult;
    }

    /**
     * 获取今日完成数
     */
    private float Andon_GetTodayFinishedFQTY(FMCStation wFMCStation,
                                             Map<Integer, List<SFCTaskSelf>> wStationIDTaskSelfListMap) {
        float wResult = 0.0f;
        try {
            if (!wStationIDTaskSelfListMap.containsKey(wFMCStation.ID)) {
                return wResult;
            }

            wResult = (float) wStationIDTaskSelfListMap.get(wFMCStation.ID).stream().mapToDouble(p -> p.ActNum).sum();
        } catch (Exception ex) {
            log.error("Andon_GetTodayFinishedFQTY", ex);
        }
        return wResult;
    }

    /**
     * 获取作业人员信息
     */
    private List<AndonStationStatusWorkerInfo> Andon_GetWorkerInfoList(BMSEmployee wLoginUser, FMCStation wFMCStation
            , Map<Integer, List<SFCTaskSelf>> wStationIDTaskSelfListMap, OutResult<Integer> wErrorCode) {
        List<AndonStationStatusWorkerInfo> wResult = new ArrayList<>();
        try {
            if (!wStationIDTaskSelfListMap.containsKey(wFMCStation.ID)) {
                return wResult;
            }

            List<SFCTaskSelf> wSFCTaskSelfList = wStationIDTaskSelfListMap.get(wFMCStation.ID);
            Map<Integer, List<SFCTaskSelf>> wWorkerIDTaskListMap = wSFCTaskSelfList.stream()
                    .collect(Collectors.groupingBy(SFCTaskSelf::getWorkerID));
            List<Integer> wWorkerIDList =
                    wSFCTaskSelfList.stream().map(p -> p.WorkerID).distinct().collect(Collectors.toList());
            for (int wWorkerID : wWorkerIDList) {
                List<SFCTaskSelf> wTaskList = wWorkerIDTaskListMap.get(wWorkerID);

                AndonStationStatusWorkerInfo wAndonStationStatusWorkerInfo = new AndonStationStatusWorkerInfo();
                wAndonStationStatusWorkerInfo.WorkerID = wWorkerID;
                wAndonStationStatusWorkerInfo.WorkerName = wTaskList.get(0).WorkerName;
                if (wTaskList.stream().anyMatch(p -> p.Status == SFCTaskStatus.Todo.getValue())) {
                    wAndonStationStatusWorkerInfo.Status = SFCTaskStatus.Todo.getValue();
                    wAndonStationStatusWorkerInfo.StatusText = SFCTaskStatus.Todo.getLabel();
                }
                if (wTaskList.stream().anyMatch(p -> p.Status == SFCTaskStatus.Doing.getValue())) {
                    wAndonStationStatusWorkerInfo.Status = SFCTaskStatus.Doing.getValue();
                    wAndonStationStatusWorkerInfo.StatusText = SFCTaskStatus.Doing.getLabel();
                }
                if (wTaskList.stream().allMatch(p -> p.Status == SFCTaskStatus.Done.getValue())) {
                    wAndonStationStatusWorkerInfo.Status = SFCTaskStatus.Done.getValue();
                    wAndonStationStatusWorkerInfo.StatusText = SFCTaskStatus.Done.getLabel();
                }
                wResult.add(wAndonStationStatusWorkerInfo);
            }
        } catch (Exception ex) {
            log.error("Andon_GetWorkerInfoList", ex);
        }
        return wResult;
    }

    /**
     * 获取工位的实时状态
     */
    private int Andon_GetStationStatus(BMSEmployee wLoginUser, FMCStation wFMCStation, Map<Integer,
            List<SFCTaskSelf>> wStationIDTaskSelfListMap, Map<Integer,
            List<EXCUnusualTask>> wStationIDExcListMap, OutResult<Integer> wErrorCode) {
        int wResult = AndonStationStatusTypes.Idle.getValue();
        try {
            if (wStationIDTaskSelfListMap.containsKey(wFMCStation.ID)) {
                List<SFCTaskSelf> wSFCTaskSelfList = wStationIDTaskSelfListMap.get(wFMCStation.ID);
                if (wSFCTaskSelfList.stream().anyMatch(p -> p.Status == SFCTaskStatus.Todo.getValue())) {
                    wResult = AndonStationStatusTypes.ToExecute.getValue();
                }
                if (wSFCTaskSelfList.stream().anyMatch(p -> p.Status == SFCTaskStatus.Doing.getValue())) {
                    wResult = AndonStationStatusTypes.Processing.getValue();
                }
                if (wSFCTaskSelfList.stream().allMatch(p -> p.Status == SFCTaskStatus.Done.getValue())) {
                    wResult = AndonStationStatusTypes.Completed.getValue();
                }
            }
            if (wStationIDExcListMap.containsKey(wFMCStation.ID)) {
                wResult = AndonStationStatusTypes.Abnormal.getValue();
            }
        } catch (Exception ex) {
            log.error("Andon_GetStationStatus", ex);
        }
        return wResult;
    }
    //endregion

    //region 生产状态看板
    /**
     * 安灯生产状态数据-缓存
     */
    public static AndonProductData mAndonProductData = new AndonProductData();

    @Override
    public ServiceResult<AndonProductData> Andon_QueryProductData(BMSEmployee wLoginUser) {
        ServiceResult<AndonProductData> wResult = new ServiceResult<>();
        wResult.Result = new AndonProductData();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            wResult.Result = mAndonProductData;

            wResult.setFaultCode(ExceptionTypes.getEnumType(wErrorCode.Result).getLabel());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            log.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> Andon_UpdateProductStatusData(BMSEmployee wLoginUser) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            //①更新今日完成情况
            mAndonProductData.TodayList = Andon_GetFinishSituationListByTpye(wLoginUser, AndonFinishSituationType.Day
                    , wErrorCode);
            //②更新订单合格率
            mAndonProductData.OrderRateList = Andon_GetOrderRateList(wLoginUser, wErrorCode);
            //③更新产品合格率
            mAndonProductData.ProductRateList = Andon_GetProductRateList(wLoginUser, wErrorCode);
            //④更新生产计划信息
            mAndonProductData.OrderList = Andon_GetOrderList(wLoginUser, wErrorCode);
            //⑤更新周完成情况
            mAndonProductData.WeekList = Andon_GetFinishSituationListByTpye(wLoginUser, AndonFinishSituationType.Week
                    , wErrorCode);
            //⑥更新生产异常信息
            mAndonProductData.ExcTaskList = Andon_GetExcTaskList(wLoginUser, wErrorCode);
            //⑦更新生产计划进度
            mAndonProductData.TaskPartList = Andon_getTaskPartList(wLoginUser, wErrorCode);
            //⑧更新月完成情况
            mAndonProductData.MonthList = Andon_GetFinishSituationListByTpye(wLoginUser,
                    AndonFinishSituationType.Month, wErrorCode);
            //⑨更新设备资产信息
            mAndonProductData.DeviceLedgerList = Andon_GetDeviceLedgerList(wLoginUser, wErrorCode);
            //⑩更新设备故障信息
            mAndonProductData.DeviceAlarmList = Andon_GetDeviceAlarmList(wLoginUser, wErrorCode);
            //①更新每日完成数
            mAndonProductData.TodayFinishMap = Andon_GetTodayFinishMap(wLoginUser, wErrorCode);

            wResult.setFaultCode(ExceptionTypes.getEnumType(wErrorCode.Result).getLabel());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            log.error(e.toString());
        }
        return wResult;
    }

    /**
     * 获取今日完成数map
     */
    private List<AndonTodayFinishNum> Andon_GetTodayFinishMap(BMSEmployee wLoginUser, OutResult<Integer> wErrorCode) {
        List<AndonTodayFinishNum> wResult = new ArrayList<>();
        try {
            Calendar wSTime = CalendarTool.getDate();
            wSTime.add(Calendar.DATE, -4);
            Calendar wETime = CalendarTool.getDateMaxMill();

            Map<String, Object> wParams = new HashMap<String, Object>();
            wParams.put("StationDateStartTime", wSTime);
            wParams.put("StationDateEndTime", wETime);
            wParams.put("Status", "2,3,4,5,6");
            List<APSTaskPartPointDay> wTodayTaskPartPointDayList = mAPSTaskPartPointDayService.SelectPOList(wLoginUser,
                    wParams, Pagination.getNewMaxSize(),
                    wErrorCode);

            //根据订单获取尾工序数据
            List<Integer> wOrderIDList =
                    wTodayTaskPartPointDayList.stream().map(p -> p.OrderID).distinct().collect(Collectors.toList());
            List<AndonOrderLastPartPointInfo> wAndonOrderLastPartPointInfoList =
                    GetAndonOrderLastPartPointInfoList(wLoginUser, wOrderIDList, wErrorCode);
            //筛选尾工序，并计算实际成品完成数
            wTodayTaskPartPointDayList =
                    wTodayTaskPartPointDayList.stream().filter(p -> wAndonOrderLastPartPointInfoList.stream().anyMatch(q -> q.OrderID == p.OrderID
                            && q.LastPartPointID == p.RoutePartPointID)).collect(Collectors.toList());
            if (wTodayTaskPartPointDayList.size() > 0) {
                Optional<AndonOrderLastPartPointInfo> first;
                for (APSTaskPartPointDay apsTaskPartPointDay : wTodayTaskPartPointDayList) {
                    first =
                            wAndonOrderLastPartPointInfoList.stream().filter(p -> p.OrderID == apsTaskPartPointDay.OrderID
                                    && p.LastPartPointID == apsTaskPartPointDay.RoutePartPointID).findFirst();
                    if (!first.isPresent()) {
                        continue;
                    }

                    AndonOrderLastPartPointInfo andonOrderLastPartPointInfo = first.get();
                    switch (PDMComponentTypes.getEnumType(andonOrderLastPartPointInfo.ComponentType)) {
                        case Component://元件
                        case Core://芯子
                            apsTaskPartPointDay.ActNum =
                                    apsTaskPartPointDay.ActNum / andonOrderLastPartPointInfo.Proportion;
                            break;
                        case Product://成品
                            break;
                        case Box://箱子
                            apsTaskPartPointDay.ActNum =
                                    apsTaskPartPointDay.ActNum * andonOrderLastPartPointInfo.Proportion;
                            break;
                    }

                    //保留一位小数
                    apsTaskPartPointDay.ActNum =
                            new BigDecimal(apsTaskPartPointDay.ActNum).setScale(1, RoundingMode.HALF_UP).floatValue();
                }
            }

            Map<Calendar, List<APSTaskPartPointDay>> wRoutePartNameTaskListMap = wTodayTaskPartPointDayList.stream()
                    .collect(Collectors.groupingBy(APSTaskPartPointDay::getStationDate));
            List<Calendar> wStationDateList =
                    wTodayTaskPartPointDayList.stream().map(p -> p.StationDate).distinct().sorted(Comparator.comparing(p -> p, Comparator.reverseOrder())).collect(Collectors.toList());
            SimpleDateFormat wSDF = new SimpleDateFormat("MM-dd");

            Calendar wNowDate = Calendar.getInstance();
            SimpleDateFormat wSDF1 = new SimpleDateFormat("yyyy-MM-dd");
            for (int i = 1; i <= 5; i++) {
                String wCurrentDate = wSDF1.format(wNowDate.getTime());
                if (wStationDateList.stream().anyMatch(p -> wSDF1.format(p.getTime()).equals(wCurrentDate))) {
                    Calendar wCalendar =
                            wStationDateList.stream().filter(p -> wSDF1.format(p.getTime()).equals(wCurrentDate)).findFirst().get();
                    List<APSTaskPartPointDay> wList = wRoutePartNameTaskListMap.get(wCalendar);
                    float wFQTY = (float) wList.stream().mapToDouble(p -> p.ActNum).sum();
                    wResult.add(new AndonTodayFinishNum(wSDF.format(wCalendar.getTime()), wFQTY));
                } else {
                    wResult.add(new AndonTodayFinishNum(wSDF.format(wNowDate.getTime()), 0));
                }
                wNowDate.add(Calendar.DATE, -1);
            }

        } catch (Exception ex) {
            log.error("Andon_GetTodayFinishMap", ex);
        }
        return wResult;
    }

    private List<AndonOrderLastPartPointInfo> GetAndonOrderLastPartPointInfoList(BMSEmployee wLoginUser,
                                                                                 List<Integer> wOrderIDList,
                                                                                 OutResult<Integer> wErrorCode) {
        List<AndonOrderLastPartPointInfo> wResult = new ArrayList<>();
        try {
            if (wOrderIDList == null || wOrderIDList.size() <= 0) {
                return wResult;
            }

            //①查询订单数据
            Map<String, Object> wParams = new HashMap<String, Object>();
            List<OMSOrder> omsOrders = mOMSOrderService.SelectPOList(wLoginUser, wOrderIDList, wParams,
                    Pagination.getNewMaxSize(),
                    wErrorCode);
            if (omsOrders == null || omsOrders.size() <= 0) {
                return wResult;
            }
            //②根据工艺ID查询工艺工序集合
            List<Integer> wRouteIDList = omsOrders.stream().map(p -> p.RouteID).distinct().collect(Collectors.toList());
            wParams.clear();
            wParams.put("RouteID", StringUtils.Join(",", wRouteIDList));
            wParams.put("Active", 1);
            List<FPCRoutePartPoint> fpcRoutePartPoints = mFPCRoutePartPointService.SelectPOList(wLoginUser, wParams,
                    Pagination.getNewMaxSize(),
                    wErrorCode);
            if (fpcRoutePartPoints == null || fpcRoutePartPoints.size() <= 0) {
                return wResult;
            }
            //③提取产品信息，查询产品组成
            List<Integer> wProductIDList = fpcRoutePartPoints.stream().map(p -> p.ProductID).distinct()
                    .collect(Collectors.toList());
            wParams.clear();
            wParams.put("ProductID", StringUtils.Join(",", wProductIDList));
            List<FPCProductCom> fpcProductComs = mFPCProductComService.SelectPOList(wLoginUser, wParams,
                    Pagination.getNewMaxSize(),
                    wErrorCode);
            if (fpcProductComs == null || fpcProductComs.size() <= 0) {
                return wResult;
            }
            //④遍历订单，赋值尾工序，产品换算比例
            AndonOrderLastPartPointInfo wAndonOrderLastPartPointInfo;
            for (OMSOrder omsOrder : omsOrders) {
                //查找尾工序，若没找到，跳过
                Optional<FPCRoutePartPoint> first =
                        fpcRoutePartPoints.stream().filter(p -> p.RouteID == omsOrder.RouteID
                                && (p.NextPartPointID == null || p.NextPartPointID.size() <= 0)).findFirst();
                if (!first.isPresent()) {
                    continue;
                }

                FPCRoutePartPoint wLastPartPoint = first.get();
                int proportion = 1;
                switch (PDMComponentTypes.getEnumType(wLastPartPoint.ComponentType)) {
                    case Component://元件
                        Optional<FPCProductCom> first1 =
                                fpcProductComs.stream().filter(p -> p.ProductID == omsOrder.ProductID
                                        && p.ComponentType == PDMComponentTypes.Component.getValue()
                                        && p.TargetComponentType == PDMComponentTypes.Product.getValue()).findFirst();
                        if (first1.isPresent()) {
                            proportion = (int) first1.get().ComponentNumber;
                        }
                        break;
                    case Core://芯子
                        Optional<FPCProductCom> first2 =
                                fpcProductComs.stream().filter(p -> p.ProductID == omsOrder.ProductID
                                        && p.ComponentType == PDMComponentTypes.Core.getValue()
                                        && p.TargetComponentType == PDMComponentTypes.Product.getValue()).findFirst();
                        if (first2.isPresent()) {
                            proportion = (int) first2.get().ComponentNumber;
                        }
                        break;
                    case Product://成品
                        proportion = 1;
                        break;
                    case Box://箱子
                        Optional<FPCProductCom> first3 =
                                fpcProductComs.stream().filter(p -> p.ProductID == omsOrder.ProductID
                                        && p.ComponentType == PDMComponentTypes.Product.getValue()
                                        && p.TargetComponentType == PDMComponentTypes.Box.getValue()).findFirst();
                        if (first3.isPresent()) {
                            proportion = (int) first3.get().ComponentNumber;
                        }
                        break;
                }

                wAndonOrderLastPartPointInfo = new AndonOrderLastPartPointInfo(omsOrder.ID,
                        wLastPartPoint.ID, wLastPartPoint.ComponentType, proportion);
                wResult.add(wAndonOrderLastPartPointInfo);
            }
        } catch (Exception ex) {
            log.error("Andon_GetOrderLastPartPointInfoList", ex);
        }
        return wResult;
    }

    /**
     * 更新设备故障信息
     */
    private List<DMSDeviceAlarm> Andon_GetDeviceAlarmList(BMSEmployee wLoginUser, OutResult<Integer> wErrorCode) {
        List<DMSDeviceAlarm> wResult = new ArrayList<DMSDeviceAlarm>();
        try {
            wResult = DMSServiceImpl.getInstance().DMS_CurrentDeviceAlarmList(wLoginUser, -1, "", "",
                    -1, -1, -1, -1, -1, "", -1, -1).Result;
        } catch (Exception e) {
            log.error("Andon_GetDeviceAlarmList", e);
        }
        return wResult;
    }

    /**
     * 获取设备资产信息
     */
    private List<DMSDeviceLedger> Andon_GetDeviceLedgerList(BMSEmployee wLoginUser, OutResult<Integer> wErrorCode) {
        List<DMSDeviceLedger> wResult = new ArrayList<DMSDeviceLedger>();
        try {
            //设备实时状态查询
            List<DMSDeviceStatus> wDMSDeviceStatusList =
                    DMSServiceImpl.getInstance().DMS_CurrentDeviceStatusList(wLoginUser,
                            -1, "", "", "", -1, -1, -1, -1, -1, -1, Pagination.getNewMaxSize()).Result;
            Map<Integer, DMSDeviceStatus> wDeviceIDStatusMap =
                    wDMSDeviceStatusList.stream().collect(Collectors.toMap(DMSDeviceStatus::getDeviceID
                            , p -> p));

            Map<String, Object> wParams = new HashMap<String, Object>();
            wParams.put("Active", 1);
            wResult = mDMSDeviceLedgerService.SelectPOList(wLoginUser, wParams, Pagination.getNewMaxSize(),
                    wErrorCode);
            for (DMSDeviceLedger wDMSDeviceLedger : wResult) {
                if (wDeviceIDStatusMap.containsKey(wDMSDeviceLedger.ID)) {
                    wDMSDeviceLedger.DeviceStatus = wDeviceIDStatusMap.get(wDMSDeviceLedger.ID).Status;
                }
            }
            wResult.sort(Comparator.comparing(DMSDeviceLedger::getCode));
        } catch (Exception e) {
            log.error("Andon_GetDeviceLedgerList", e);
        }
        return wResult;
    }

    /**
     * 获取月完成情况
     */
    private List<AndonFinishSituation> Andon_GetMonthList(BMSEmployee wLoginUser, OutResult<Integer> wErrorCode) {
        List<AndonFinishSituation> wResult = new ArrayList<AndonFinishSituation>();
        try {
            Calendar wMinTime = CalendarTool.getMinTimeOfCurrentMonth();
            Calendar wMaxTime = CalendarTool.getMaxTimeOfCurrentMonth();

            Map<String, Object> wParams = new HashMap<String, Object>();
            wParams.put("StationDateStartTime", wMinTime);
            wParams.put("StationDateEndTime", wMaxTime);
            wParams.put("Status", "2,3,4,5,6");
            List<APSTaskPartPointDay> wTodayTaskPartPointDayList = mAPSTaskPartPointDayService.SelectPOList(wLoginUser,
                    wParams, Pagination.getNewMaxSize(),
                    wErrorCode);
            Map<String, List<APSTaskPartPointDay>> wRoutePartNameTaskListMap = wTodayTaskPartPointDayList.stream()
                    .collect(Collectors.groupingBy(APSTaskPartPointDay::getRoutePartName));

            List<String> wRoutePartNameList = new ArrayList<>(Arrays.asList("卷制工艺", "定型工艺", "喷金工艺", "赋能工艺", "芯子工艺",
                    "真空注胶工艺", "试验工艺", "成品装箱工艺"));
            for (String wRoutePartName : wRoutePartNameList) {
                if (!wRoutePartNameTaskListMap.containsKey(wRoutePartName)) {
                    AndonFinishSituation wAndonFinishSituation = new AndonFinishSituation(wRoutePartName, 0, 0, 0);
                    wResult.add(wAndonFinishSituation);
                    continue;
                }

                List<APSTaskPartPointDay> wList = wRoutePartNameTaskListMap.get(wRoutePartName);
                float planFQTY = (float) wList.stream().mapToDouble(p -> p.PlantNum).sum();
                float finishFQTY = (float) wList.stream().mapToDouble(p -> p.ActNum).sum();
                float finishRate = 0;
                if (planFQTY > 0) {
                    finishRate = new BigDecimal(finishFQTY / planFQTY)
                            .setScale(3, RoundingMode.DOWN).floatValue();
                }

                AndonFinishSituation wAndonFinishSituation = new AndonFinishSituation(wRoutePartName, planFQTY,
                        finishFQTY, finishRate);
                wResult.add(wAndonFinishSituation);
            }
        } catch (Exception e) {
            log.error("Andon_GetMonthList", e);
        }
        return wResult;
    }

    /**
     * 获取生产计划进度
     */
    private List<APSTaskPart> Andon_getTaskPartList(BMSEmployee wLoginUser, OutResult<Integer> wErrorCode) {
        List<APSTaskPart> wResult = new ArrayList<APSTaskPart>();
        try {
            Map<String, Object> wParams = new HashMap<String, Object>();
            wParams.put("Status", "2,3,4,5");
            wParams.put("ShiftPeriod", APSShiftPeriod.Week.getValue());
            wParams.put("Active", 1);
            wParams.put("IsCurrent", 1);
            wParams.put("OrderStatus", OMSOrderStatus.Producing.getValue());
            wResult = mAPSTaskPartService.SelectPOList(wLoginUser, wParams, Pagination.getNewMaxSize(),
                    wErrorCode);
            wResult.sort(Comparator.comparing(APSTaskPart::getOrderID, Comparator.reverseOrder())
                    .thenComparing(APSTaskPart::getRoutePartID));
        } catch (Exception e) {
            log.error("Andon_getTaskPartList", e);
        }
        return wResult;
    }

    /**
     * 获取生产异常信息
     */
    private List<EXCUnusualTask> Andon_GetExcTaskList(BMSEmployee wLoginUser, OutResult<Integer> wErrorCode) {
        List<EXCUnusualTask> wResult = new ArrayList<EXCUnusualTask>();
        try {
            Map<String, Object> wParams = new HashMap<String, Object>();
            wParams.put("Status", "2,3");
            wResult = mEXCUnusualTaskService.SelectPOList(wLoginUser, wParams, Pagination.getNewMaxSize(),
                    wErrorCode);
        } catch (Exception e) {
            log.error("Andon_GetExcTaskList", e);
        }
        return wResult;
    }

    /**
     * 获取周完成情况
     */
    private List<AndonFinishSituation> Andon_GetFinishSituationListByTpye(BMSEmployee wLoginUser,
                                                                          AndonFinishSituationType wType,
                                                                          OutResult<Integer> wErrorCode) {
        List<AndonFinishSituation> wResult = new ArrayList<AndonFinishSituation>();
        try {
            Calendar wMinTime = Calendar.getInstance();
            Calendar wMaxTime = Calendar.getInstance();
            switch (wType) {
                case Default:
                case Year:
                    break;
                case Day:
                    wMinTime.set(wMinTime.get(Calendar.YEAR), wMinTime.get(Calendar.MONTH),
                            wMinTime.get(Calendar.DATE), 0, 0
                            , 0);
                    wMinTime.set(Calendar.MILLISECOND, 0);

                    wMaxTime.set(wMinTime.get(Calendar.YEAR), wMinTime.get(Calendar.MONTH),
                            wMinTime.get(Calendar.DATE), 23,
                            59, 59);
                    break;
                case Week:
                    wMinTime = CalendarTool.getMinTimeOfCurrentWeek();
                    wMaxTime = CalendarTool.getMaxTimeOfCurrentWeek();
                    break;
                case Month:
                    wMinTime = CalendarTool.getMinTimeOfCurrentMonth();
                    wMaxTime = CalendarTool.getMaxTimeOfCurrentMonth();
                    break;
            }
            wResult = Andon_GetFinishSituationList(wLoginUser, wMinTime, wMaxTime, wType, wErrorCode);
        } catch (Exception e) {
            log.error("Andon_GetWeekList", e);
        }
        return wResult;
    }

    /**
     * 获取周完成情况
     */
    private List<AndonFinishSituation> Andon_GetFinishSituationList(BMSEmployee wLoginUser, Calendar wMinTime,
                                                                    Calendar wMaxTime, AndonFinishSituationType wType
            , OutResult<Integer> wErrorCode) {
        List<AndonFinishSituation> wResult = new ArrayList<AndonFinishSituation>();
        try {
            Map<String, Object> wParams = new HashMap<String, Object>();
            wParams.put("StationDateStartTime", wMinTime);
            wParams.put("StationDateEndTime", wMaxTime);
            wParams.put("Status", "2,3,4,5,6");
            List<APSTaskPartPointDay> wTodayTaskPartPointDayList = mAPSTaskPartPointDayService.SelectPOList(wLoginUser,
                    wParams, Pagination.getNewMaxSize(),
                    wErrorCode);
            Map<String, List<APSTaskPartPointDay>> wRoutePartNameTaskListMap = wTodayTaskPartPointDayList.stream()
                    .collect(Collectors.groupingBy(APSTaskPartPointDay::getRoutePartName));

            List<String> wRoutePartNameList = new ArrayList<>(Arrays.asList("卷制工艺", "定型工艺", "喷金工艺", "赋能工艺", "芯子工艺",
                    "真空注胶工艺", "试验工艺", "成品装箱工艺"));

            //获取订单ID集合
            List<Integer> wOrderIDList =
                    wTodayTaskPartPointDayList.stream().map(p -> p.OrderID).distinct().collect(Collectors.toList());
            //根据订单查询工序计划集合
            List<APSTaskPartPoint> apsTaskPartPoints = new ArrayList<>();
            if (wOrderIDList.size() > 0) {
                wParams.clear();
                wParams.put("IsCurrent", 1);
                wParams.put("Active", 1);
                wParams.put("OrderID", StringUtils.Join(",", wOrderIDList));
                apsTaskPartPoints = mAPSTaskPartPointService.SelectPOList(wLoginUser, wParams,
                        Pagination.getNewMaxSize(),
                        wErrorCode);
            }

            Map<Integer, List<APSTaskPartPointDay>> wOrderIDTaskListMap;
            List<APSTaskPartPointDay> apsTaskPartPointDays;
            for (String wRoutePartName : wRoutePartNameList) {

                //计算计划数
                float wPlantNum = GetPlantNum(apsTaskPartPoints, wRoutePartName, wOrderIDList, wMinTime, wMaxTime,
                        wType);

                if (!wRoutePartNameTaskListMap.containsKey(wRoutePartName)) {
                    AndonFinishSituation wAndonFinishSituation = new AndonFinishSituation(wRoutePartName, wPlantNum,
                            0, 0);
                    wResult.add(wAndonFinishSituation);
                    continue;
                }

                List<APSTaskPartPointDay> wList = wRoutePartNameTaskListMap.get(wRoutePartName);
                wOrderIDTaskListMap = wList.stream()
                        .collect(Collectors.groupingBy(APSTaskPartPointDay::getOrderID));

                float finishFQTY = 0;
                float planFQTY = 0;
                for (Integer integer : wOrderIDTaskListMap.keySet()) {
                    //按照订单，获取最大的工序
                    apsTaskPartPointDays = wOrderIDTaskListMap.get(integer);

                    //获取计划的尾端工序
                    Optional<APSTaskPartPoint> max =
                            apsTaskPartPoints.stream().filter(p -> p.OrderID == integer && p.RoutePartName.equals(wRoutePartName)).max(Comparator.comparing(APSTaskPartPoint::getRoutePartPointOrder));
                    if (max.isPresent()) {
                        APSTaskPartPoint apsTaskPartPoint = max.get();

                        //查找最大工序的所有日计划，统计计划与完成数
                        apsTaskPartPointDays =
                                apsTaskPartPointDays.stream().filter(p -> p.RoutePartPointID == apsTaskPartPoint.RoutePartPointID).collect(Collectors.toList());
                        for (APSTaskPartPointDay apsTaskPartPointDay : apsTaskPartPointDays) {
                            finishFQTY += apsTaskPartPointDay.ActNum;
                            if (wType == AndonFinishSituationType.Day) {
                                planFQTY += apsTaskPartPointDay.PlantNum;
                            }
                        }
                    }
                }

                if (planFQTY > 0) {
                    wPlantNum = planFQTY;
                }

                float finishRate = 0;
                if (wPlantNum > 0) {
                    finishRate = new BigDecimal(finishFQTY / wPlantNum)
                            .setScale(3, RoundingMode.DOWN).floatValue();
                }

                AndonFinishSituation wAndonFinishSituation = new AndonFinishSituation(wRoutePartName, wPlantNum,
                        finishFQTY, finishRate);
                wResult.add(wAndonFinishSituation);
            }
        } catch (Exception e) {
            log.error("Andon_GetWeekList", e);
        }
        return wResult;
    }

    /**
     * 获取工艺计划数
     */
    private float GetPlantNum(List<APSTaskPartPoint> apsTaskPartPoints, String wRoutePartName,
                              List<Integer> wOrderIDList, Calendar wMinTime, Calendar wMaxTime,
                              AndonFinishSituationType wType) {
        float wResult = 0;
        try {
            if (wOrderIDList == null || wOrderIDList.size() <= 0) {
                return wResult;
            }

            OutResult<Integer> wErrorCode = new OutResult<Integer>(0);

            for (int wOrderID : wOrderIDList) {
                List<APSTaskPartPoint> wOrderTaskPartPointList =
                        apsTaskPartPoints.stream().filter(p -> p.OrderID == wOrderID).collect(Collectors.toList());
                if (wOrderTaskPartPointList == null || wOrderTaskPartPointList.size() <= 0) {
                    continue;
                }

                List<APSTaskPartPoint> wRoutePartTaskPartPointList =
                        wOrderTaskPartPointList.stream().filter(p -> p.RoutePartName.equals(wRoutePartName)).collect(Collectors.toList());
                if (wRoutePartTaskPartPointList == null || wRoutePartTaskPartPointList.size() <= 0) {
                    continue;
                }

                //获取最大工序
                APSTaskPartPoint wMaxAPSTaskPartPoint =
                        wRoutePartTaskPartPointList.stream().max(Comparator.comparing(APSTaskPartPoint::getRoutePartPointOrder)).get();

                //查询工艺计划
                Map<String, Object> wParams = new HashMap<String, Object>();
                wParams.put("ID", wMaxAPSTaskPartPoint.TaskPartID);
                APSTaskPart apsTaskPart = mAPSTaskPartService.SelectPO(BMSEmployee.SysAdmin, wParams,
                        wErrorCode);

                for (String wDayStr : wMaxAPSTaskPartPoint.PlanDayNum.keySet()) {
                    Calendar wDay = StringUtils.parseCalendar(wDayStr);

                    //如果是周、月计划，且计划结束日期小于wday，则跳过
                    if (wType != AndonFinishSituationType.Day && apsTaskPart.PartEndTime.compareTo(wDay) < 0) {
                        continue;
                    }

                    if (wDay.compareTo(wMinTime) >= 0 && wDay.compareTo(wMaxTime) <= 0) {
                        wResult += wMaxAPSTaskPartPoint.PlanDayNum.get(wDayStr);
                    }
                }
            }
        } catch (Exception ex) {
            log.error("GetPlantNum", ex);
        }
        return wResult;
    }

    /**
     * 获取生产计划信息
     */
    private List<OMSOrder> Andon_GetOrderList(BMSEmployee wLoginUser, OutResult<Integer> wErrorCode) {
        List<OMSOrder> wResult = new ArrayList<OMSOrder>();
        try {
            Map<String, Object> wParams = new HashMap<String, Object>();
            wParams.put("Status", "4,5");
            wResult = mOMSOrderService.SelectPOList(wLoginUser, wParams, Pagination.getNewMaxSize(),
                    wErrorCode);
        } catch (Exception e) {
            log.error("Andon_GetOrderList", e);
        }
        return wResult;
    }

    /**
     * 获取产品合格率
     */
    private List<AndonProductRate> Andon_GetProductRateList(BMSEmployee wLoginUser, OutResult<Integer> wErrorCode) {
        List<AndonProductRate> wResult = new ArrayList<AndonProductRate>();
        try {
            //①查询最新的已检验产品
            List<Integer> wProductIDList = SFCWorkpieceRecordDAO.getInstance().SFC_GetNewProductIDList(wLoginUser, 4,
                    wErrorCode);
            if (wProductIDList == null || wProductIDList.size() == 0) {
                return wResult;
            }
            //②查询产品数据
            Map<String, Object> wParams = new HashMap<String, Object>();
            List<FPCProduct> wProductList = mFPCProductService.SelectPOList(wLoginUser, wProductIDList, wParams,
                    Pagination.getNewMaxSize(),
                    wErrorCode);
            if (wProductList == null || wProductList.size() == 0) {
                return wResult;
            }
            Map<Integer, String> wIDCodeProductMap =
                    wProductList.stream().collect(Collectors.toMap(FPCProduct::getID
                            , FPCProduct::getCode));
            //③获取数据
            wResult = SFCWorkpieceRecordDAO.getInstance().SFC_QueryProductRateList(wLoginUser, wIDCodeProductMap,
                    wProductIDList, wErrorCode);
        } catch (Exception e) {
            log.error("Andon_GetProductRateList", e);
        }
        return wResult;

    }

    /**
     * 获取订单合格率
     */
    private List<AndonOrderRate> Andon_GetOrderRateList(BMSEmployee wLoginUser, OutResult<Integer> wErrorCode) {
        List<AndonOrderRate> wResult = new ArrayList<AndonOrderRate>();
        try {
            //①查询最新的已检验订单
            List<Integer> wOrderIDList = SFCWorkpieceRecordDAO.getInstance().SFC_GetNewOrderIDList(wLoginUser, 4,
                    wErrorCode);
            if (wOrderIDList == null || wOrderIDList.size() == 0) {
                return wResult;
            }
            //②查询订单数据
            Map<String, Object> wParams = new HashMap<String, Object>();
            List<OMSOrder> wOrderList = mOMSOrderService.SelectPOList(wLoginUser, wOrderIDList, wParams,
                    Pagination.getNewMaxSize(),
                    wErrorCode);
            if (wOrderList == null || wOrderList.size() == 0) {
                return wResult;
            }
            Map<Integer, String> wIDCodeOrderMap =
                    wOrderList.stream().collect(Collectors.toMap(OMSOrder::getID
                            , OMSOrder::getCode));
            //②获取数据
            wResult = SFCWorkpieceRecordDAO.getInstance().SFC_QueryOrderRateList(wLoginUser, wIDCodeOrderMap,
                    wOrderIDList, wErrorCode);
        } catch (Exception e) {
            log.error("Andon_GetOrderRateList", e);
        }
        return wResult;
    }

    /**
     * 获取今日完成情况
     */
    private List<AndonFinishSituation> Andon_GetTodayList(BMSEmployee wLoginUser, OutResult<Integer> wErrorCode) {
        List<AndonFinishSituation> wResult = new ArrayList<AndonFinishSituation>();
        try {
            Calendar wSTime = Calendar.getInstance();
            wSTime.set(wSTime.get(Calendar.YEAR), wSTime.get(Calendar.MONTH), wSTime.get(Calendar.DATE), 0, 0, 0);
            wSTime.set(Calendar.MILLISECOND, 0);

            Calendar wETime = Calendar.getInstance();
            wETime.set(wSTime.get(Calendar.YEAR), wSTime.get(Calendar.MONTH), wSTime.get(Calendar.DATE), 23, 59, 59);

            Map<String, Object> wParams = new HashMap<String, Object>();
            wParams.put("StationDateStartTime", wSTime);
            wParams.put("StationDateEndTime", wETime);
            wParams.put("Status", "2,3,4,5,6");
            List<APSTaskPartPointDay> wTodayTaskPartPointDayList = mAPSTaskPartPointDayService.SelectPOList(wLoginUser,
                    wParams, Pagination.getNewMaxSize(),
                    wErrorCode);
            Map<String, List<APSTaskPartPointDay>> wRoutePartNameTaskListMap = wTodayTaskPartPointDayList.stream()
                    .collect(Collectors.groupingBy(APSTaskPartPointDay::getRoutePartName));

            List<String> wRoutePartNameList = new ArrayList<>(Arrays.asList("卷制工艺", "定型工艺", "喷金工艺", "赋能工艺", "芯子工艺",
                    "真空注胶工艺", "试验工艺", "成品装箱工艺"));
            for (String wRoutePartName : wRoutePartNameList) {
                if (!wRoutePartNameTaskListMap.containsKey(wRoutePartName)) {
                    AndonFinishSituation wAndonFinishSituation = new AndonFinishSituation(wRoutePartName, 0, 0, 0);
                    wResult.add(wAndonFinishSituation);
                    continue;
                }

                List<APSTaskPartPointDay> wList = wRoutePartNameTaskListMap.get(wRoutePartName);
                float planFQTY = (float) wList.stream().mapToDouble(p -> p.PlantNum).sum();
                float finishFQTY = (float) wList.stream().mapToDouble(p -> p.ActNum).sum();
                float finishRate = 0;
                if (planFQTY > 0) {
                    finishRate = new BigDecimal(finishFQTY / planFQTY)
                            .setScale(3, RoundingMode.DOWN).floatValue();
                }

                AndonFinishSituation wAndonFinishSituation = new AndonFinishSituation(wRoutePartName, planFQTY,
                        finishFQTY, finishRate);
                wResult.add(wAndonFinishSituation);
            }
        } catch (Exception e) {
            log.error("Andon_GetTodayList", e);
        }
        return wResult;
    }

    //endregion
}
